package com.example.sulingorder.service.impl;

import com.alibaba.fastjson.JSON;
import com.example.sulingorder.conster.RedisConster;
import com.example.sulingorder.service.RedisUtilsService;
import com.example.sulingorder.vo.HelpFormDataVo;
import com.example.sulingorder.vo.HelpRedisDataVo;
import com.example.sulingorder.vo.RedisOrderAllVo;
import com.xiao.sulingpublic.myutils.MyUtils;
import com.xiao.sulingpublic.utils.R;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.data.redis.core.script.DefaultRedisScript;
import org.springframework.stereotype.Service;

import java.math.BigDecimal;
import java.util.*;
import java.util.concurrent.TimeUnit;

/**
 * @author: 1322127758@qq.com
 * @date: 2022/3/16 16:53
 * @作用: redis相关操作
 */
@Service("redisUtilsService")
public class RedisUtilsServiceImpl implements RedisUtilsService {
    @Autowired
    private StringRedisTemplate redisTemplate;

    /**
     * 一个获取表单接口防刷接口用户code函数
     * @param id 用户账号
     * @return 返回表单唯一code值
     */
    @Override
    public String getRedisFormCode(String id) {
        String code = UUID.randomUUID().toString().replace("-", "").substring(0, 6);

        String key = RedisConster.FORM_CODE_KEY + id;

        redisTemplate.opsForValue().set(key,code,3, TimeUnit.DAYS);

        return code;
    }

    /**
     * 一个验证code的函数
     * @param key code在redis中的key值
     * @param code 验证的code
     * @return 返回验证结果
     */
    @Override
    public boolean testRedisFormCode(String key, String code) {
        //获取订单在spring-session的token,判断是否一致,一致后删除,然后处理业务   HINT:注意 这条注释的操作需要为原子操作
        //同时判断是否有值和删除, 需要表达式才行:
        //   表达式说明: 传一个key 和 value 如果这个key存在并且value等于我们传的值 删除这个数据返回1,
        //   返回0就是没有这个key或者value不一样.
        String strUte = "if redis.call('get',KEYS[1]) == ARGV[1] then return redis.call('del',KEYS[1]) else return 0 end";
        /*
         * 参数一: DefaultRedisScript 参数一:要执行的脚本  参数二:返回值类型 如果这个key存在并且value等于我们传的值
         * 删除这个数据返回1,返回0就是没有这个key或者value不一样.
         * 参数二: 要获取的key
         * 参数三: 要判断的值
         */
        Long execute = redisTemplate.execute(
                new DefaultRedisScript<>(strUte, Long.class),
                Collections.singletonList(key),
                code);
        if(null != execute && 1 == execute){
            //验证令牌成功
            return true;
        }
        //验证令牌失败
        return false;
    }

    @Override
    public R getOrderData(String username, String orderSn) {

        String s = redisTemplate.opsForValue().get(RedisConster.ORDER_KEY+username + ":" + orderSn);
        HelpFormDataVo helpFormDataVo = JSON.parseObject(s, HelpFormDataVo.class);

        return R.ok().put("helpFormDataVo",helpFormDataVo);
    }

    @Override
    public R getOrderAll(String latitude, String longitude, String scope) {

        Set<String> keys = redisTemplate.keys(RedisConster.ORDER_KEY + "*");
        List<String> strings = redisTemplate.opsForValue().multiGet(keys);

        //获取要查询的订单范围
        String rangeByLatLon = MyUtils.getRangeByLatLon(new BigDecimal(longitude), new BigDecimal(latitude), Integer.parseInt(scope));
        String[] split = rangeByLatLon.split("-");
        //比minlng,minlat这个大 比maxlat,maxlng这个小
        //eturn minlng + "-" + maxlng + "-" + minlat + "-" + maxlat;

        List<RedisOrderAllVo> redisOrderAllVoList = new ArrayList<>();
        for (String string : strings) {

            RedisOrderAllVo redisOrderAllVo = new RedisOrderAllVo();

            HelpRedisDataVo helpRedisDataVo = JSON.parseObject(string, HelpRedisDataVo.class);
            if(helpRedisDataVo.getOrOrderClassifyId() == null || helpRedisDataVo.getOrOrderClassifyId() != 0){
                HelpFormDataVo helpFormDataVo = JSON.parseObject(string, HelpFormDataVo.class);
                //过滤数据
                String purposeLatitude = helpFormDataVo.getOrderEarthEntity().getPurposeLatitude();
                String purposeLongitude = helpFormDataVo.getOrderEarthEntity().getPurposeLongitude();


                if (new BigDecimal(purposeLatitude).compareTo(new BigDecimal(split[2])) < 0 || new BigDecimal(purposeLongitude).compareTo(new BigDecimal(split[0])) < 0) {
                    continue;
                }
                // 比较之前确保a,b对象不能为空
                if (new BigDecimal(purposeLatitude).compareTo(new BigDecimal(split[3])) > 0 || new BigDecimal(purposeLongitude).compareTo(new BigDecimal(split[1])) > 0) {
                    continue;
                }


                redisOrderAllVo.setOrOrderClassifyId(1);
                redisOrderAllVo.setHelpFormDataVo(helpFormDataVo);

                redisOrderAllVoList.add(redisOrderAllVo);
            }else{
                String purposeLatitude = helpRedisDataVo.getOrderEarthEntity().getPurposeLatitude();
                String purposeLongitude = helpRedisDataVo.getOrderEarthEntity().getPurposeLongitude();
                //过滤数据
                // 比较之前确保a,b对象不能为空
                if (new BigDecimal(purposeLatitude).compareTo(new BigDecimal(split[2])) < 0 || new BigDecimal(purposeLongitude).compareTo(new BigDecimal(split[0])) < 0) {
                    continue;
                }
                // 比较之前确保a,b对象不能为空
                if (new BigDecimal(purposeLatitude).compareTo(new BigDecimal(split[3])) > 0 || new BigDecimal(purposeLongitude).compareTo(new BigDecimal(split[1])) > 0) {
                    continue;
                }

                redisOrderAllVo.setOrOrderClassifyId(Math.toIntExact(helpRedisDataVo.getOrOrderClassifyId()));
                redisOrderAllVo.setHelpRedisDataVo(helpRedisDataVo);
                redisOrderAllVoList.add(redisOrderAllVo);
            }

        }

        return R.ok().put("redisOrderAllVoList",redisOrderAllVoList);
    }
}
